﻿using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace LitBT
{
    /// <summary>
    /// 行为树
    /// </summary>
    [CreateAssetMenu(menuName = "LitBT/BehaviourTree")]
    public class BehaviourTree : ScriptableObject
    {
        public Node rootNode;
        public Node.State treeState = Node.State.Running;
        public List<Node> nodes = new List<Node>();

        public Node.State Update()
        {
            if (rootNode.state == Node.State.Running)
                treeState = rootNode.Update();
            return treeState;
        }

#if UNITY_EDITOR
        public Node CreateNode(System.Type type)
        {
            Node node = CreateInstance(type) as Node;
            node.name = type.Name;
            node.guid = GUID.Generate().ToString();
            nodes.Add(node);

            AssetDatabase.AddObjectToAsset(node, this);
            AssetDatabase.SaveAssets();

            return node;
        }


        public void DeleteNode(Node node)
        {
            nodes.Remove(node);
            AssetDatabase.RemoveObjectFromAsset(node);
            AssetDatabase.SaveAssets();
        }
#endif

        public void AddChild(Node parent, Node child)
        {
            DecoratorNode decoratorNode = parent as DecoratorNode;
            if (decoratorNode)
            {
                decoratorNode.child = child;
            }

            RootNode rootNode = parent as RootNode;
            if (rootNode)
            {
                rootNode.child = child;
            }

            CompositeNode composite = parent as CompositeNode;
            if (composite)
            {
                composite.children.Add(child);
            }
        }

        public void RemoveChild(Node parent, Node child)
        {
            DecoratorNode decoratorNode = parent as DecoratorNode;
            if (decoratorNode)
            {
                decoratorNode.child = null;
            }

            RootNode rootNode = parent as RootNode;
            if (rootNode)
            {
                rootNode.child = null;
            }

            CompositeNode composite = parent as CompositeNode;
            if (composite)
            {
                composite.children.Remove(child);
            }
        }

        public List<Node> GetChildren(Node parent)
        {
            List<Node> children = new List<Node>();
            DecoratorNode decoratorNode = parent as DecoratorNode;
            if (decoratorNode && decoratorNode.child != null)
            {
                children.Add(decoratorNode.child);
            }

            RootNode rootNode = parent as RootNode;
            if (rootNode && rootNode.child != null)
            {
                children.Add(rootNode.child);
            }

            CompositeNode composite = parent as CompositeNode;
            if (composite)
            {
                return composite.children;
            }
            return children;
        }

        public BehaviourTree Clone()
        {
            BehaviourTree tree = Instantiate(this);
            tree.rootNode = tree.rootNode.Clone();
            return tree;
        }
    }
}